/**
 * 二维矩阵，每格有一面镜子
 * 给定起点和出射方向，问最终能有几个镜子反射光线，多个询问
 * 
 * 注意到光链是独立的，不可能有中途汇入的情况，因此某点射出的光线只有两种情况：循环和射出
 * 
 * 又注意到光路是可逆的，因此无需对矩阵中的每个点进行搜索，可以将矩阵的外围作为起点，向矩阵内射入光线，
 * 这些光线一定会从某个地方再次射出来。将此种情况的光路分为两种：
 * 1. 原路返回的，此种情况的充要条件是路径终点为'|'或者'-'。此情况下假设一共有x个镜子反射了光线，
 *    则往里射入的方向答案都是x，往外射出的方向，则需要逐个加1，注意一个镜子可能反射两次光线。
 * 2. 从其他地方射出。将光路正反走一遍，每次根据镜子以及反射情况加1即可。
 * 
 * 经过上述处理后，还没有计算出的位置与方向一定是环路。任选一个未处理的点与方向作为光源，进行搜索即可。
 * 再次碰到相同点与方向，就表明搜索出了一条完整的环路，此环路上的答案均为反射镜子的数量。
 * 
 * 预搜索完毕直接回答即可。
 * 
 * 每个点与方向最多搜索一遍，因此时间是O(N^2 + Q)
 */
#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std;

using llt = long long;
using vi = vector<int>;
using vll = vector<llt>;

template<typename T>
istream & operator >> (istream & is, vector<T> & v){
    for(auto & i : v) is >> i;
    return is;
}

template<typename T>
void input(vector<T> & v, int n){
    v.assign(n + 1, {});
    for(int i=1;i<=n;++i) cin >> v[i];
    return;
}

struct pair_hash{
    std::size_t operator () (const pair<int, int> & p) const {
        return (std::size_t)p.first * 13313 + p.second;
    }
};

struct tuple_hash{
    size_t operator () (const tuple<int, int, int> & p) const {
        auto [a, b, c] = p;
        return (((size_t)a * 13313) + b) * 13313 + c;
    }
};

map<string, int> S2I {
    {"above", 0},
    {"below", 1},
    {"left", 2},
    {"right", 3}
};

int const DR[] = {-1, 1, 0, 0};
int const DC[] = {0, 0, -1, 1};

int N, M;
vector<string> Board;
int Q;

vector<vector<array<int, 4>>> D;
vector<tuple<int, int, int>> Queue;
unordered_map<pair<int ,int>, int, pair_hash> Map;

int f(int o, char c){
    if(0 == o or 1 == o){
        if('|' == c) return o;
        if('-' == c) return o ^ 1;
        if('/' == c) return 0 == o ? 3 : 2;
        return 0 == o ? 2 : 3;
    }

    if('|' == c) return o ^ 1;
    if('-' == c) return o;

    if('/' == c) return 2 == o ? 1 : 0;
    return 2 == o ? 0 : 1;
}

bool isOver(int x, int y, int o){
    if(x < 1 or x > N or y < 1 or y > M) return true;
    if((0 == o or 1 == o) and '-' == Board[x][y]) return true;
    if((2 == o or 3 == o) and '|' == Board[x][y]) return true;
    return false;
}

bool canReflex(char c, int o){
    if('/' == c or '\\' == c) return true;
    if('-' == c and o <= 1) return true;
    if('|' == c and o > 1) return true;
    return false;
}

int reverse(char c, int o){
    switch(c){
        case '-': return o ^ 1;
        case '|': return o ^ 1;
        case '/': return o ^ 2;
        case '\\': return o ^ 3;
    }
    return -10000;
}

void recordBackLian(){
    assert(Queue.size() >= 2);
    auto [lastx, lasty, lasto] = Queue.back();
    assert((Board[lastx][lasty] == '-' and (lasto <= 1)) or (Board[lastx][lasty] == '|' and (lasto & 2)));

    Map.clear();
    for(auto it=Queue.begin()+1,et=Queue.end();it!=et;++it){
        auto [x, y, o] = *it;
        if(canReflex(Board[x][y], o)){
            Map[{x, y}] += 1;
        }
    }

    int ans = 0;
    int mirCnt = Map.size();
    Map.clear();
    for(auto it=Queue.begin()+1,et=Queue.end()-1;it!=et;++it){
        auto [x, y, o] = *it;
        int ro = reverse(Board[x][y], o);
        
        D[x][y][o] = mirCnt;
        D[x][y][ro] = Map.size();
        if(canReflex(Board[x][y], ro)){
            Map[{x, y}] += 1;
        } 
        if(not (it!=Queue.end()-1 or (ans == mirCnt))){
            throw runtime_error(to_string(ans) + ", " + to_string(mirCnt));
        }
    }
    std::tie(lastx, lasty, lasto) = Queue.back();
    D[lastx][lasty][lasto] = mirCnt - 1;

    std::tie(lastx, lasty, lasto) = Queue.front();
    D[lastx][lasty][lasto] = mirCnt; // not important

#ifndef ONLINE_JUDGE
    cout << "BackLian:" << endl;
    for(const auto [x,y,o] : Queue){
        cout << "(" << x << ", " << y << ")" << "--" << o << "-->";
    }
    cout << endl;
    cout << "D:" << endl;
    for(const auto [x,y,o] : Queue){
        cout << "D[" << x << "][" << y << "] = {" << D[x][y][0] << ", " << D[x][y][1] << ", " << D[x][y][2] << ", " << D[x][y][3] << "}" << endl;
    }
#endif
    return;
}

void recordDanLian(){
    assert(Queue.size() >= 3);

    Map.clear();
    for(auto it=Queue.begin()+1,et=Queue.end()-1;it!=et;++it){
        auto [x, y, o] = *it;
        o = reverse(Board[x][y], o);
        D[x][y][o] = Map.size();
        if(canReflex(Board[x][y], o)){
            Map[{x, y}] += 1;
        }
    }

    Map.clear();
    for(auto it=Queue.rbegin()+1,et=Queue.rend()-1;it!=et;++it){
        auto [x, y, o] = *it;

        D[x][y][o] = Map.size();
        if(canReflex(Board[x][y], o)){
            Map[{x, y}] += 1;
        }
    }   

    auto [x, y, o] = Queue.front();
    D[x][y][o] = Map.size();
    std::tie(x, y, o) = Queue.back();
    o ^= 1;
    D[x][y][o] = Map.size();

#ifndef ONLINE_JUDGE
    cout << "DanLian:" << endl;
    for(const auto [x,y,o] : Queue){
        cout << "(" << x << ", " << y << ")" << "--" << o << "-->";
    }
    cout << endl;
    cout << "D:" << endl;
    for(const auto [x,y,o] : Queue){
        cout << "D[" << x << "][" << y << "] = {" << D[x][y][0] << ", " << D[x][y][1] << ", " << D[x][y][2] << ", " << D[x][y][3] << "}" << endl;
    }
#endif

    return;
}

void searchLian(int startr, int startc, int emito){
    Queue.clear();
    Queue.emplace_back(startr, startc, emito);

    while(1){
        auto [x, y, o] = Queue.back();
        int nr = x + DR[o];
        int nc = y + DC[o];
        int no = o;
        
        if(1 <= nr and nr <= N and 1 <= nc and nc <= M){
            no = f(o, Board[nr][nc]);
        }else{
            // no = -1;
        }
        
        Queue.emplace_back(nr, nc, no);
        if(isOver(nr, nc, no)) break;
    }

    auto [lastx, lasty, lasto] = Queue.back();
    if(1 <= lastx and lastx <= N and 1 <= lasty and lasty <= M){
        recordBackLian();
    }else{
        recordDanLian();
    }    

    return;
}

void searchHuan(int startr, int startc, int emito){
    unordered_set<tuple<int, int, int>, tuple_hash> tupleSet;

    Queue.clear();
    Queue.emplace_back(startr, startc, emito);    
    tupleSet.insert({startr, startc, emito});

    while(1){
        auto [x, y, o] = Queue.back();
        int nr = x + DR[o];
        int nc = y + DC[o];
        assert((1 <= nr and nr <= N and 1 <= nc and nc <= M));
        int no = f(o, Board[nr][nc]);

        auto tt = tupleSet.find({nr, nc, no});
        if(tt != tupleSet.end()) break;
        tupleSet.insert(tt, {nr, nc, no});
        Queue.emplace_back(nr, nc, no);
    }

    Map.clear();
    for(auto [x, y, o] : Queue){
        if(canReflex(Board[x][y], o)){
            Map[{x, y}] += 1;
        }        
    }

    int mirCnt = Map.size();
    for(auto [x, y, o] : Queue){
        int ro = reverse(Board[x][y], o);
        D[x][y][o] = mirCnt;
        if('-' != Board[x][y] and '|' != Board[x][y]){
            D[x][y][ro] = mirCnt;
        }
    }

#ifndef ONLINE_JUDGE
    cout << "Huan:" << endl;
    for(const auto [x,y,o] : Queue){
        cout << "(" << x << ", " << y << ")" << "--" << o << "-->";
    }
    cout << endl;
    cout << "D:" << endl;
    for(const auto [x,y,o] : Queue){
        cout << "D[" << x << "][" << y << "] = {" << D[x][y][0] << ", " << D[x][y][1] << ", " << D[x][y][2] << ", " << D[x][y][3] << "}" << endl;
    }    
#endif

    return;
}

void work(){
    cin >> N >> M;
    Board.assign(N + 1, {});
    for(int i=1;i<=N;++i){
        cin >> Board[i];
        Board[i] = " " + Board[i];
    }

    D.assign(N + 2, vector<array<int, 4>>(M + 2, {-1, -1, -1, -1}));

    for(int i=1;i<=N;++i){
        if(-1 == D[i][0][3]){
            searchLian(i, 0, 3);
        }        
        if(-1 == D[i][M + 1][2]){
            searchLian(i, M + 1, 2);
        } 
    }
    for(int i=1;i<=M;++i){
        if(-1 == D[0][i][1]){
            searchLian(0, i, 1);
        }
        if(-1 == D[N + 1][i][0]){
            searchLian(N + 1, i, 0);
        }        
    }
    for(int i=1;i<=N;++i)for(int j=1;j<=M;++j){
        for(int o=0;o<4;++o){
            if(-1 == D[i][j][o]){
                searchHuan(i, j, o);
            }
        }
    }
#ifndef ONLINE_JUDGE
    cout << "ALL:" << endl;
    for(int x=1;x<=N;++x){
        for(int y=1;y<=M;++y){
            cout << "D[" << x << "][" << y << "] = {" << D[x][y][0] << ", " << D[x][y][1] << ", " << D[x][y][2] << ", " << D[x][y][3] << "}" << endl;
        }
    }
#endif
 
    cin >> Q;
    string s;
    for(int r,c,o,q=1;q<=Q;++q){
        cin >> r >> c >> s;
        o = S2I[s];
        auto ans = D[r][c][o];
        cout << ans << "\n";
    }
    return;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int nofkase = 1;
    // cin >> nofkase;
    while(nofkase--) work();
    return 0;
}